package dgo.tilemap;

import dgo.*;
import starruby.Texture;
import org.json.me.JSONArray;
import org.json.me.JSONObject;
import java.util.Hashtable;


public class MapLoader {
public static MapChipset[] loadChipsets(Class cls, String modelData,  byte gridWidth, byte gridHeight){
    JSONArray model = null;
    try{
      model = (new JSONArray(modelData));
    } catch (org.json.me.JSONException e) {
      System.out.println("Couldn't get JSONArray for chipsets");
    }

    MapChipset[] chipsets = new MapChipset[model.length()];
    try{ 
      for(int i = 0; i < model.length(); i++){
        JSONObject o = (JSONObject)(model.get(i));
        if((o.get("type")).equals("base")){
          chipsets[i] = loadBaseChipset(cls, (String)o.get("id"), gridWidth, gridHeight);
        }
        if((o.get("type")).equals("anime")){
        }
      }
    } catch (org.json.me.JSONException e) { 
      System.out.println(e.toString());
    }
     
    return chipsets;
  }
  
  public static PaletChip[][][] loadLayers(String modelData, MapChipset[] chipsets, byte xCount, byte yCount){
    JSONArray model = null;
    try{
      model = (new JSONArray(modelData));
    } catch (org.json.me.JSONException e) {
      System.out.println("Couldn't get JSONArray for chipsets");
    }
    
    PaletChip[][][] layers = new PaletChip[model.length()][xCount][yCount];

    try{
      int t = 0;
      for(int i = 0; i < model.length(); i++){
        String[] lines = MyLib.split((String)model.get(i), "\n");
        t = 0;
        for(int j = 0; j < lines.length; j++){
          String[] chips = MyLib.split(lines[j], ",");
          for(int k = 0; k < chips.length; k++){
            if(!chips[k].equals("")){
              String[] chipInfo = MyLib.split(chips[k], "-");
              PaletChip p = chipsets[Byte.parseByte(chipInfo[0])].paletChips[Integer.parseInt(chipInfo[1])];
 
              layers[i][k][j] = p;
            }
          }
        }
      }
    } catch (org.json.me.JSONException e) {
      System.out.println("Couldn't read layer");
    }
    return layers;
  }
  
  public static BaseChipset loadBaseChipset(Class cls, String id, int gridWidth, int gridHeight){
    JSONObject info = null;
    try 
    {
      info = new JSONObject(IO.readTextFile(cls, "/data/chipsets/base/" + id + ".json"));
    } catch (org.json.me.JSONException e) {
      System.out.println("Couldn't loadBaseChipset");
    }
    
    BaseChipset c = new BaseChipset("game/map/base/" + id, id, gridWidth, gridHeight);
    
    setChipsetAttr(c, info);
    return c;
  }
  
  static void setChipsetAttr(MapChipset chipset, JSONObject info){
    if(info == null){return;}
    try  {
      for(int i=0; i < chipset.paletChips.length; i++){
        chipset.paletChips[i].collisioniType = Byte.parseByte(info.getJSONArray("collision").getString(i));
        chipset.paletChips[i].priority = Byte.parseByte(info.getJSONArray("priority").getString(i));
      }
    } catch (org.json.me.JSONException e) {
      System.out.println("setChipsetAttr Failed");
    }
  }
  
  static byte[][] loadCollisions(PaletChip[][][] layers, int xCount, int yCount){
       // merge collision data
       byte[][] collisionArr = new byte[xCount][yCount];
       for(int i=0; i < collisionArr.length; i++){
         for(int j=0; j < collisionArr[i].length; j++){
          collisionArr[i][j] = CollisionType.NONE;
         }
       }
       
       for(int i=0; i < xCount; i++){
         for(int j=0; j < yCount; j++){
           for(int k=0; k < layers.length; k++){

             PaletChip p = layers[k][i][j];
             if(p != null){
               if(p.priority == 0){
                 collisionArr[i][j] = p.collisioniType;
                 //System.out.println("i: " + i + "j: " + j + "value: " + collisionArr[i][j]);
               }else{
                 collisionArr[i][j] |= p.collisioniType;
               }
               //if(k == 0) System.out.println("i: " + i + "j: " + j + "value: " + collisionArr[i][j]);
             }
           }
         }
       }

       return collisionArr;
  }
  
  /*
  * Load Panorama
  */
  private static Texture loadPanorama(String panoramaName){
    return Texture.load("game/panorama/" + panoramaName);
  }
          
  public static Map loadMap(Class cls, String id){
    Hashtable result = new Hashtable();
    
    Hashtable info = IO.readHashFromJSON(cls, "/data/map/" + id + ".json");
    byte gw = Byte.parseByte((String)info.get("gw"));
    byte gh = Byte.parseByte((String)info.get("gh"));
    byte xCount = Byte.parseByte((String)info.get("x_count"));
    byte yCount = Byte.parseByte((String)info.get("y_count"));
    
    MapChipset[] chipsets = loadChipsets(cls, (String)info.get("chipsets"),  gw, gh);
    
    PaletChip[][][] layers = loadLayers((String)info.get("layers"), chipsets, xCount, yCount);
    byte[][] collisionData = loadCollisions(layers, xCount, yCount);
    
    Texture panoramaTexture = null;

    if(info.containsKey("panorama")){
      panoramaTexture = loadPanorama((String)info.get("panorama"));
    }
    
    Map m = new Map(
      Byte.parseByte((String)info.get("x_count")), 
      Byte.parseByte((String)info.get("y_count")), 
      layers, 
      (byte)15, 
      (byte)15, 
      Byte.parseByte((String)info.get("gw")),
      Byte.parseByte((String)info.get("gh")),
      collisionData,
      panoramaTexture
    );
    
    return m;
  }
}
